package RJZ.Rainbow.Controller;

import RJZ.Rainbow.Service.ChequerService;
import RJZ.Rainbow.Service.OrderService;
import RJZ.Rainbow.Config.Information;
import RJZ.Rainbow.Protocol.OrderProtocol;
import RJZ.Rainbow.Tools.ArguementsUtils;
import com.alibaba.fastjson.JSON;
import io.netty.bootstrap.Bootstrap;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.codec.LineBasedFrameDecoder;
import io.netty.handler.codec.string.StringDecoder;
import io.netty.handler.codec.string.StringEncoder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.PropertySource;
import org.springframework.stereotype.Controller;

import java.net.InetSocketAddress;

import static java.lang.Thread.sleep;

@PropertySource("classpath:connection.properties")
@Controller
public class OrderController implements Runnable {
    Channel ch;

    @Autowired
    Information imfor;
    @Autowired
    OrderService orderService;
    @Autowired
    ChequerService chequerService;
    @Autowired
    UIConruoller uiConruoller;
    @Autowired
    ArguementsUtils arguementsUtils;
    @Autowired
    OrderProtocol orderProtocol;

    private boolean link = false;

    public boolean isLink() {
        return link;
    }

    public void setLink(boolean link) {
        this.link = link;
    }

    public Channel getCh() {
        return ch;
    }


    public void link() {
        NioEventLoopGroup group = new NioEventLoopGroup();
        ChannelFuture bs = new Bootstrap()
                .group(group)
                .channel(NioSocketChannel.class)
                .handler(new ChannelInitializer<NioSocketChannel>() {
                    protected void initChannel(NioSocketChannel ch) throws Exception {
                        ch.pipeline().addLast(new LineBasedFrameDecoder(2048));
                        ch.pipeline().addLast(new StringEncoder());
                        ch.pipeline().addLast(new StringDecoder());
                        ch.pipeline().addLast("input", new ChannelInboundHandlerAdapter() {
                            public void channelActive(ChannelHandlerContext ctx) {
                                System.out.println("网络连接成功");
                                setLink(true);

                                String retry = "{" +
                                        "\"Cop\":" + "\"RJZ\","
                                        + "\"box_id\":" + "\"" + imfor.getId() + "\","
                                        + "\"emptynum\":" + "\"" + chequerService.emptyNum() + "\","
                                        + "\"managecode\":" + "\"" + imfor.getCode() + "\""
                                        + "}" + '\n';
                                ch.writeAndFlush(retry);
                            }

                            @Override
                            public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
                                super.channelRead(ctx, msg);
                                //operation(msg.toString());
                                System.out.println(msg);
                                arguementsUtils.prepareArguements(JSON.parseObject(msg.toString()));
                                //System.out.println("Cop:"+arguementsUtils.getCop());
                                //System.out.println("args:"+arguementsUtils.getArglist());
                                orderProtocol.match(arguementsUtils.getCop(), arguementsUtils.getArglist());
                            }

                            public void channelInactive(ChannelHandlerContext ctx) throws Exception {
                                ctx.fireChannelInactive();
                                System.out.println("网络连接断开");
                                setLink(false);
                                link();
                            }

                        });
                    }
                })
                .connect(new InetSocketAddress(imfor.getIp(), imfor.getPort()));
        ch = bs.channel();
    }

    @Override
    public void run() {
        while (true) {
            if (link) {
                String retry = "{" +
                        "\"Cop\":" + "\"RJZ\","
                        + "\"box_id\":" + "\"" + imfor.getId() + "\","
                        + "\"emptynum\":" + "\"" + chequerService.emptyNum() + "\","
                        + "\"managecode\":" + "\"" + imfor.getCode() + "\""
                        + "}" + '\n';
                ch.writeAndFlush(retry);
            } else {
                link();
            }
            try {
                sleep(2000);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }

        }
    }
}
